package com.custom.action.core;

import com.custom.action.core.methods.MethodKind;
import com.custom.action.core.plugin.InterceptHandler;
import com.custom.action.core.plugin.Invocation;
import com.custom.action.interfaces.ExecuteHandler;
import com.custom.jdbc.session.JdbcSqlSessionFactory;

/**
 * @author XiaoBai
 * @since 2024/1/15 14:06
 * 执行的静态代理类，用做插件拦截
 */
public class CustomExecutorProxy implements ExecuteHandler {
    private final ExecuteHandler targetHandler;
    private final MethodKind methodKind;
    private Class<?> mappedType;
    private final InterceptHandler interceptHandler = new InterceptHandler();

    public CustomExecutorProxy(MethodKind methodKind, Executor executor) throws Exception {
        this.methodKind = methodKind;
        this.targetHandler = executor.getInstance(methodKind);
    }



    @Override
    public <T> Object startExecute(JdbcSqlSessionFactory sqlSessionFactory, Class<T> target, Object[] params) throws Exception {
        Invocation invocation = new Invocation(targetHandler,
                params, () -> targetHandler.startExecute(sqlSessionFactory, target, params));
        return interceptHandler.proceed(invocation, methodKind);
    }


    @Override
    @SuppressWarnings("unchecked")
    public <T> Class<T> getMappedType(Object[] params) {
        if (mappedType == null) {
            this.mappedType = targetHandler.getMappedType(params);
        }
        return (Class<T>) mappedType;
    }

    @Override
    public MethodKind getKind() {
        return targetHandler.getKind();
    }

    public interface Executor {
        ExecuteHandler getInstance(MethodKind methodKind) throws Exception;
    }
}
